﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetJavap.AttributeInfos;

namespace NetJavap.JVM
{
    public class JVMStackFrame
    {
        private Dictionary<UInt16, Object> _localVarTbl;
        private Stack<Object> _operateStack;
        private UInt32 _returnAddress;
        private CodeAttributeInfo _codeInfo;
        private JVMCodeRunner _codeRunner;
        private JavaObject _bindInstance;

        public Dictionary<UInt16, Object> LocalVariableTable { get { return this._localVarTbl; } }
        public Stack<Object> OperateStack { get { return this._operateStack; } }
        public UInt32 ReturnAddress { get { return this._returnAddress; } }
        public JVMCodeRunner CodeRunner { get { return this._codeRunner; } }
        public CodeAttributeInfo CodeInfo { get { return this._codeInfo; } }
        public JavaObject BindInstance
        {
            get
            {
                return this._bindInstance;
            }
            set
            {
                if (this._bindInstance != null)
                {
                    throw new InvalidOperationException("重复绑定实例！");
                }
                this._bindInstance = value;
            }
        }

        public JVMStackFrame(JVMCodeRunner codeRunner, CodeAttributeInfo code, JavaObject bindIns = null)
        {
            this._localVarTbl = new Dictionary<UInt16, Object>(code.MaxLocals);
            this._operateStack = new Stack<Object>(code.MaxStack);
            this._returnAddress = (UInt32)(codeRunner.CurrentOpcode == null ? 0 : codeRunner.PC + codeRunner.CurrentOpcode.OtherBytes.Length + 1);
            this._codeRunner = codeRunner;
            this._codeInfo = code;
            this._bindInstance = bindIns;
        }

        public override string ToString()
        {
            return this.CodeInfo.DefineMember.ToString();
        }
    }
}
